package edu.tec.mty.core.modules;

import java.util.HashMap;
import java.util.Vector;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import edu.tec.mty.extras.Pointer;

public class Parser extends Thread {
	
	private Pattern item = Pattern.compile("\\(\\(([^\\(\\)]+)\\)\\s*(([\\-\\d\\.\\s]*))\\)");
	private World world;
	private SelfModel playerModel;
	private boolean running = true;
	private final Lock lock = new ReentrantLock();
	private final Condition update = lock.newCondition();
	private boolean updating = false;
	private boolean closing = false;
	private String input;
	private long time = 0;
	
	public Parser(World world, SelfModel playerModel) {
		this.world = world;
		this.playerModel = playerModel;
	}
	
	public void parseFullState(String input, long step) {
		
	}
	
	public void parseSeeGlobal(String input, long step) {
		
	}
	
	public void updateInfo(String input, long time) {
		this.lock.lock();
		this.input = input;
		this.time = time;
		this.updating = true;
		this.update.signal();
		this.lock.unlock();
	}
	
	public void shutdown() {
		this.lock.lock();
		this.running = false;
		this.closing = true;
		this.updating = true;
		this.update.signal();
		this.lock.unlock();
	}
	
	private void parsePlayerSeeSensor() {
		Vector<Pointer<String, String>> members = new Vector<Pointer<String, String>>();
		HashMap<String, String> flags = new HashMap<String, String>();
		String ball = "";
		Matcher matcher = this.item.matcher(input);
		while (matcher.find()) {
			String object = matcher.group(1);
			String data = matcher.group(2);
			switch(object.charAt(0)) {
			case 'p':
				members.add(new Pointer<String, String>(object, data));
				break;
			case 'P':
				break;
			case 'f':
				if (data.split("\\s").length > 1) {
					flags.put(object, data);
				}
				break;
			case 'F':
				break;
			case 'b':
				//System.out.println(data);
				ball = data;
				break;
			case 'B':
				break;
			case 'g':
				break;
			case 'G':
				break;
			case 'l':
				break;
			}
		}
		this.playerModel.setFlags(flags, time);
		this.world.setWorldInfo(members, ball, time);
	}

	public void run() {
		while (running) {
			this.lock.lock();
			try {
				while (!this.updating) {
					this.update.await();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (!this.closing) {
				this.parsePlayerSeeSensor();
			}
			this.updating = false;
			this.lock.unlock();
		}
		System.out.println("Parser closed");
	}
	
	//Test
	
	/*public static void main(String[] args) {
		Parser parser = new Parser();
		String input = "(see 0 ((f g b) 50.6 45)((p) 45)((b) 45.7 34.6 10.5)((p \"mates\" 4) 45.6 34.7 93.4 34.6))";
	}/**/
	
}
